droptarget: Fast-path local value load
authorBenjamin Otte <otte@redhat.com>
Mon, 2 Mar 2020 20:45:59 +0000 (21:45 +0100)
committerBenjamin Otte <otte@redhat.com>
Mon, 2 Mar 2020 20:45:59 +0000 (21:45 +0100)
This way, we can ensure that for local same-type drops the GValue
is set when ::enter is emitted.

This is the common case for dnd between widgets inside larger
applications, so it's worth it to speed it up.

gtk/gtkdroptarget.c

index 093fc0af1fe51b634f1e362f3352a3264cc7d338..89e91a9a9a402b75522b9d0cec6d895995c73351 100644 (file)
@@ -222,9 +222,31 @@ gtk_drop_target_load_done (GObject      *source,
     gtk_drop_target_do_drop (self);
 }
 
+static gboolean
+gtk_drop_target_load_local (GtkDropTarget *self,
+                            GType          type)
+{
+  GdkDrag *drag;
+
+  drag = gdk_drop_get_drag (self->drop);
+  if (drag == NULL)
+    return FALSE;
+
+  g_value_init (&self->value, type);
+  if (gdk_content_provider_get_value (gdk_drag_get_content (drag),
+                                      &self->value,
+                                      NULL))
+    return TRUE;
+
+  g_value_unset (&self->value);
+  return FALSE;
+}
+
 static gboolean
 gtk_drop_target_load (GtkDropTarget *self)
 {
+  GType type;
+
   g_assert (self->drop);
 
   if (G_IS_VALUE (&self->value))
@@ -233,10 +255,15 @@ gtk_drop_target_load (GtkDropTarget *self)
   if (self->cancellable)
     return FALSE;
 
+  type = gdk_content_formats_match_gtype (self->formats, gdk_drop_get_formats (self->drop));
+
+  if (gtk_drop_target_load_local (self, type))
+    return TRUE;
+
   self->cancellable = g_cancellable_new ();
 
   gdk_drop_read_value_async (self->drop, 
-                             gdk_content_formats_match_gtype (self->formats, gdk_drop_get_formats (self->drop)),
+                             type,
                              G_PRIORITY_DEFAULT,
                              self->cancellable,
                              gtk_drop_target_load_done,